/**
 * 萨达阿斯顿敖德萨就
 */
fun main() {

    val str = "74757671657C64"
    val key = "这是密码！"

    val a = stringXorStringEncrypt(key, str)
    println(a)

    val c = hexXorStringDecrypt(key,"AA")
    println(c)

    val b2 = hexXorString(str,a)
    println(b2)

    //OA
    val a2 = hexXorHex(b2,a)
    println(a2)
}

/*
  * 加密
  * */
fun stringXorStringEncrypt(key: String, str: String): String {

    val stringBuffer = StringBuffer()
    for (i in str.toByteArray()) {
        var tmp: Int = i.toInt()
        for (j in key.toByteArray()) {
            tmp = tmp xor j.toChar().toInt()
        }
        val tmpStr: String = String.format("%02X", tmp)
        stringBuffer.append(tmpStr.substring(tmpStr.length - 2 until tmpStr.length))
    }
    return stringBuffer.toString()
}

/*
  * 解密
  * 确保字符串 str长度 是整数，否则 引发异常
  * */
fun hexXorStringDecrypt(key: String, str: String): String {

    val stringBuffer = StringBuffer(str)
    val len: Int = stringBuffer.length / 2
    val stringBuffer2 = ByteArray(len);
    for (i in 0 until len) {
        val tmpStr: String = stringBuffer.substring(i * 2, i * 2 + 2)
        var tmpInt: Int = tmpStr.toInt(16)
        for (j in key.toByteArray()) {
            tmpInt = tmpInt xor j.toChar().toInt()
        }
        stringBuffer2[i] = tmpInt.toByte()
    }
    return stringBuffer2.decodeToString()
}

// 反向推导冲突 key
fun hexXorString(key: String, str: String): String {

    val stringBuffer = StringBuffer(str)
    val len: Int = stringBuffer.length / 2
    val stringBuffer2 = ByteArray(len);
    for (i in 0 until 1) {
        val tmpStr: String = stringBuffer.substring(i * 2, i * 2 + 2)
        var tmpInt: Int = tmpStr.toInt(16)
        for (j in key.toByteArray()) {
            tmpInt = tmpInt xor j.toChar().toInt()
        }
        stringBuffer2[i] = tmpInt.toByte()
    }
    return String.format("%02X", stringBuffer2[0])
}

// 冲突key解密
fun hexXorHex(key: String, str: String): String {

    val stringBuffer = StringBuffer(str)
    val len: Int = stringBuffer.length / 2
    val stringBuffer3 = StringBuffer(key)
    val len3: Int = stringBuffer3.length / 2
    val stringBuffer2 = ByteArray(len);
    for (i in 0 until len) {
        val tmpStr: String = stringBuffer.substring(i * 2, i * 2 + 2)
        val tmpHex = tmpStr.toUByte(16)
        var tmpInt: Int = tmpHex.toInt()
        for (j in 0 until len3) {
            val tmpStr2: String = stringBuffer3.substring(j * 2, j * 2 + 2)
            val tmpHex2 = tmpStr2.toUByte(16)
            tmpInt = tmpInt xor tmpHex2.toInt()
        }
        stringBuffer2[i] = tmpInt.toByte()
    }
    return stringBuffer2.decodeToString()
}